package com.hk.seagment.springmvc.dispatcherservlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.ModelAndViewDefiningException;
import org.springframework.web.util.NestedServletException;
import org.springframework.web.util.WebUtils;

/**
 * 前端控制器分派方法
 * @author HK
 *
 */
public class DispatcherServlet extends HttpServlet{
	protected void doDispatcher(HttpServletRequest request, HttpServletResponse response) throws ServletException{
		HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;
		int interceptorIndex = -1;
		try {
			ModelAndView mv;
			boolean errorView = false;
			try{
				//检查是否是请求multipart（如文件上传），如果是将通过MutilpartResolver
				processedRequest  = checkMutilpart(request);
				//步骤2 请求到处理器（页面控制器）的映射，通过HandlerMapping进行映射
				mappedHandler = getHandler(processedRequest,response);
				if(mappedHandler == null || mappedHandler.getHandler()==null){
					noHandlerFound(processedRequest, response);
					return;
				}
				//步骤3 处理器适配，即将我们的处理器包装成相应的适配器，从而支持多种类型的处理器
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
				// 304 not Modified缓存支持
				
				//执行处理器相关的拦截器的预处理 HandlerInterceptor.preHandle
				
				//步骤4 由适配器执行处理器
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
				//do we  need view name translation
				if(mv !=null && !mv.hasView()){
					mv.setViewName(getDefaultViewName(request));
				}
				//执行处理器相关的拦截器的后处理 HandlerInterceptor.postHandle
			} catch (ModelAndViewDefiningException ex) {
//				logger.debug("ModellAndViewDefiningException encountered",ex);
				mv = ex.getModelAndView();
			}catch(Exception e){
				Object handler = (mappedHandler != null?mappedHandler.getHandler():null);
				mv = processHandlerException(processedRequest, response, handler, e);
				errorView = (mv!=null);
			}
		//步骤5 步骤6、解析视图并进行视图的渲染      
		//步骤5 由ViewResolver解析View（viewResolver.resolveViewName(viewName, locale)）      
		//步骤6 视图在渲染时会把Model传入（view.render(mv.getModelInternal(), request, response);）      
            if (mv != null && !mv.wasCleared()) {      
                render(mv, processedRequest, response);      
                if (errorView) {      
                    WebUtils.clearErrorRequestAttributes(request);      
                }      
            }      
            else {      
                if (true) {      
//		                    logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +      
//		                            "': assuming HandlerAdapter completed request handling");      
                }      
           }      
	        // 执行处理器相关的拦截器的完成后处理（HandlerInterceptor.afterCompletion）      
	        //此处省略具体代码      
		}catch (Exception ex) {      
            // Trigger after-completion for thrown exception.      
            triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);      
            throw ex;      
        }      
        catch (Error err) {      
            ServletException ex = new NestedServletException("Handler processing failed", err);      
            // Trigger after-completion for thrown exception.      
            triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);      
            throw ex;      
        }      
        finally {      
            // Clean up any resources used by a multipart request.      
            if (processedRequest != request) {      
                cleanupMultipart(processedRequest);      
            }      
        }      
	}   
	private void cleanupMultipart(HttpServletRequest processedRequest) {
		// TODO Auto-generated method stub
		
	}
	private void triggerAfterCompletion(HandlerExecutionChain mappedHandler,
			int interceptorIndex, HttpServletRequest processedRequest,
			HttpServletResponse response, Exception ex) {
		// TODO Auto-generated method stub
		
	}
	private void render(ModelAndView mv, HttpServletRequest processedRequest,
			HttpServletResponse response) {
		// TODO Auto-generated method stub
		
	}
	private ModelAndView processHandlerException(HttpServletRequest processedRequest,
			HttpServletResponse response, Object handler, Exception e) {
		// TODO Auto-generated method stub
		return null;
	}
	private String getDefaultViewName(HttpServletRequest request) {
		// TODO Auto-generated method stub
		return null;
	}
	private HandlerAdapter getHandlerAdapter(Object handler) {
		// TODO Auto-generated method stub
		return null;
	}
	private void noHandlerFound(HttpServletRequest processedRequest,
			HttpServletResponse response) {
		// TODO Auto-generated method stub
		
	}
	private HandlerExecutionChain getHandler(
			HttpServletRequest processedRequest, HttpServletResponse response) {
		// TODO Auto-generated method stub
		return null;
	}
	protected HttpServletRequest checkMutilpart(HttpServletRequest request){
		return null;
	}
}
